'use strict';

import { Platform } from 'react-native';
import { log, logErr, logWarm } from './utils/logs';


let domain = 'http://guofangchao.com/warehous';
// debug
// domain = 'http://192.168.1.117:3000/warehous'

/**
 * 默认的头信息
 */
let headers = {
    platform: Platform.OS,
}
/**
 * 设置headers头
 * @param {*} name 
 * @param {*} value 
 */
exports.setHeader = function (name, value) {
    if (!name) return;
    headers[name] = value;
}
/**
 * 获取头的信息
 * @param {*} name 
 * @param {*} value 
 */
exports.getHeader = function (name, value) {
    if (!name) return "";
    return headers[name] || '';
}
/**
 * 获取所有headers
 */
exports.getHeaders = function () {
    return headers;
}
/**
 * 混合参数
 * @param {*} data 
 */
let urlEncoded = (data) => {
    if (typeof data == 'string') return encodeURIComponent(data);
    let params = [];
    for (let k in data) {
        if (!data.hasOwnProperty(k)) return;
        let v = data[k];
        if (typeof v == 'string') v = encodeURIComponent(v);
        if (v == undefined) v = '';
        params.push(`${encodeURIComponent(k)}=${v}`);
    }
    return params.join('&');
}
/**
 * 等待几毫秒
 * @param {*} time 
 */
function sleep(time) {
    return new Promise(function (a, b) {
        setTimeout(() => {
            a();
        }, time);
    })
}
let authFailureHandler = () => { }
/**
 * 请求库
 */
class Request {
    /**
     * 重试次数
     */
    retryCount = 5

    constructor() { }
    /**
     * 检测返回状态码
     * @param {*} status
     * @param {*} res
     */
    async _checkStatus(status, res, url) {
        if (status !== 200) {
            logWarm('请求失败参数', await res.text(), url, headers);
            throw new Error('网络连接失败，请检查网络');
        }
    }
    /**
     * 检查后端返回的状态码
     * @param {*} status
     */
    _checkAppStatus(json, url) {
        if (json.code != undefined && json.code != 1) {
            logWarm('返回状态报错', json, url);
            throw new Error(`${json.errorMsg}`);
        }
    }
    /**
     * 内部实现网络请求
     * @param {*} url
     * @param {*} options
     */
    async _request(url, options, type, retry) {
        url = url.indexOf('http') == 0 ? url : domain + url;
        let res = await this._fetch(url, options, retry);
        this._checkStatus(res.status, res, url)
        if (type === 'json') return await this._jsonFactory(res, url, options)
        return await this._jsonFactory(res, url, options)
    }
    /**
     * 包装fetch方法
     * @param {*} url
     * @param {*} options
     */
    async _fetch(url, options, retry) {
        let res;
        let count = 1;
        try {
            res = await fetch(url, options);
        } catch (e) {
            log('请求失败', e.message);
            throw new Error('网络连接失败，请检查网络权限');
        }
        while (retry && res.status === 420 && count < this.retryCount) {
            await sleep(2000)
            try {
                res = await fetch(url, options);
            } catch (e) {
                logWarm('网络错误', e, url);
                throw new Error('网络连接失败，请检查网络');
            }
            count++;
        }
        if (res.status === 420) throw new Error('排队人多,再来一次');
        return res;
    }

    /**
     * 处理json数据
     * @param {*} res
     * @param {*} url
     */
    async _jsonFactory(res, url, options) {
        let json;
        let txt = '';
        try {
            // json = await res.json();
            txt = await res.text();
        } catch (e) {
            log('未拿到返回字符串', { url: url, txt: txt });
            throw new Error('数据格式错误');
        }
        try {
            json = JSON.parse(txt);
        } catch (e) {
            logErr('返回数据格式错误', { url: url, txt: txt });
            throw new Error('数据格式错误');
        }
        this._checkAppStatus(json, url)
        log("请求返回", json, url, options);
        return json;
    }
    /**
     * get请求
     * @param {*} url
     */
    async get(url, data, retry) {
        if (data) data = urlEncoded(data);
        if (url.indexOf('?') < 0 && data) url += '?' + data;
        return this._request(url, {
            method: 'GET',
            headers: headers,
            timeout: 10000
        }, 'json', retry)
    }
    /**
     * post请求
     * @param {*} url
     * @param {*} data
     */
    async post(url, data, retry) {
        return this._request(url, {
            method: 'POST',
            headers: Object.assign(headers, { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }),
            timeout: 10000,
            body: urlEncoded(data)
        }, 'json', retry)
    }
    /**
     * 上传图片
     * @param {*} url
     * @param {*} data
     */
    async uploadImage(url, data) {
        return this._request(url, {
            method: 'POST',
            headers: Object.assign({}, headers, {
                'Content-Type': 'multipart/form-data;charset=utf-8'
            }),
            body: data
        });
    }

}
export default new Request();
